package com.google.code.drift.service;

import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.code.drift.api.AppSkyApp;
import com.google.code.drift.api.UserInfo;
import com.google.code.drift.async_task.ChangeLocationTask;
import com.google.code.drift.async_task.HeartbeatTask;
import com.google.code.drift.async_task.LoginTask;
import com.google.code.drift.utils.DLog;
import com.google.code.drift.utils.JsonFactory;
import com.google.code.drift.utils.JsonParser;
import com.google.code.drift.utils.CommonUtils;
import com.google.code.drift.utils.PreferencesProxy;
import com.google.code.drift.utils.PreferencesProxy.PrefKey;

public class DriftService extends Service {

	private AppSkyApp app;

	private ServerConnection connection;

	private HeartbeatTask heartbeatTask;

	private JsonParser jsonParser;

	private boolean messageMonitorFlag = true;

	private boolean isRegisterReceiver = false;

	private IBinder mBinder = new DriftServiceBinder();

	@Override
	public void onCreate() {
		DLog.i("Service is onCreate");
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO bindService出来的服务不会调用这个
		super.onStart(intent, startId);
	}

	@Override
	public IBinder onBind(Intent intent) {
		app = (AppSkyApp) getApplication();
		// 如果为null，说明Activity已经死了
		if (app == null) {
			stopSelf();
		} else {
			initMyInfoFromPreference();

			LoginTask loginTask = new MyLoginTask(this);
			loginTask.execute("");
		}
		return mBinder;
	}

	@Override
	public void onDestroy() {
		clearUp();
		DLog.i("Service已销毁");
		super.onDestroy();
	}

	public class DriftServiceBinder extends Binder {
		public DriftService getService() {
			return DriftService.this;
		}
	}

	public void reLogin() {
		LoginTask loginTask = new MyLoginTask(this);
		loginTask.execute("");
	}

	class MyLoginTask extends LoginTask {

		public MyLoginTask(Context context) {
			super(context);
			if (connection != null) {
				connection.closeIOAndSocket();
			}
		}

		@Override
		protected void onPreExecute() {
			Message msg = new Message();
			Bundle bundle = new Bundle();
			bundle.putString("showMessage", "正在登录..");
			msg.setData(bundle);
			msg.what = CommonUtils.START_PROGRESS;
			app.sendMessageToHandler(msg);
		}

		@Override
		protected void onPostExecute(Integer flag) {
			app.sendEmptyMessageToHandler(flag);
			if (flag == CommonUtils.LOGIN_SUCCESS
					|| flag == CommonUtils.REGISTER_SUCCESS) {
				connection = ServerConnection.getConnection();
				app.setLoginState(true);
				startReceverMessageThread();
				IntentFilter filter = new IntentFilter(
						CommonUtils.ACTION_SEND_MESSAGE);
				filter.addAction(CommonUtils.ACTION_SEND_MESSAGE_FOR_TIMEOUT);
				isRegisterReceiver = true;
				registerReceiver(sendMessageReceiver, filter);

				// TODO 心跳 暂时有问题。。。郁闷
				// heartbeatTask = new
				// HeartbeatTask(app.getMyInfo().getUserId());
				// heartbeatTask.start();
			}
		}
	}

	/*
	 * class MyChangeLocationTask extends ChangeLocationTask {
	 * 
	 * public MyChangeLocationTask(Context context) { super(context); }
	 * 
	 * @Override protected void onPreExecute() { Message msg = new Message();
	 * Bundle bundle = new Bundle(); bundle.putString("showMessage",
	 * "正在更改位置.."); msg.setData(bundle); msg.what = CommonUtils.START_PROGRESS;
	 * app.sendMessageToHandler(msg); }
	 * 
	 * @Override protected void onPostExecute(Integer flag) {
	 * app.sendEmptyMessageToHandler(flag); } }
	 */

	private void initMyInfoFromPreference() {

		setupLocationToMyInfo();

		app.getMyInfo().setNick(PreferencesProxy.getString(PrefKey.MY_NICK));
		app.getMyInfo().setSex(PreferencesProxy.getInt(PrefKey.MY_SEX));
		app.getMyInfo().setUserId(PreferencesProxy.getInt(PrefKey.MY_ID));
		app.setAutoRefresh(PreferencesProxy.getBoolean(PrefKey.AUTO_REFRESH));
		app.setChatRing(PreferencesProxy.getBoolean(PrefKey.PLAY_CHAT_RING));
		app.setChatVibrator(PreferencesProxy.getBoolean(PrefKey.CHAT_VIBRATOR));
	}

	private synchronized void setupLocationToMyInfo() {
		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			Location location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			if (location != null) {
				// XXX 添加这个加减会更准确，民间偏方...
				app.getMyInfo().setLocation(
						(int) (location.getLatitude() * 1000000 - 2500),
						(int) (location.getLongitude() * 1000000 + 4500));
			} else {
				DLog.e("location == null");
			}
		} else {
			DLog.i("network已关闭");
		}
	}

	private BroadcastReceiver sendMessageReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equals(CommonUtils.ACTION_SEND_MESSAGE)) {
				// 发送消息
				DLog.i("DriftService: 发送一个消息！");
				String jsonString = intent.getStringExtra("json");
				sendMessageFromClient(jsonString);
			} else if (action
					.equals(CommonUtils.ACTION_SEND_MESSAGE_FOR_TIMEOUT)) {
				DLog.i("DriftService: 发送一个有超时时间的消息！");
				String jsonString = intent.getStringExtra("json");
				int timeout = intent.getIntExtra("timeout", 0);
				sendMessageFromClientForTimeout(jsonString, timeout);
			}
		}
	};

	private void sendMessageFromClientForTimeout(String message, int timeout) {
		try {
			connection.setSocketTimeout(timeout);
			sendMessageFromClient(message);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	private void sendMessageFromClient(String message) {
		try {
			connection.sendMessage(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void startReceverMessageThread() {
		Thread monitorThread = new Thread() {
			@Override
			public void run() {
				String message = null;
				while (messageMonitorFlag) {
					try {
						message = connection.readMessage();
						if (message != null) {
							DLog.i("监听到消息：" + message);
							handlingAndDispatchMessage(message);
						} else {
							messageMonitorFlag = false;
						}
						if (connection.getSocketTimeout() != 0) {
							connection.setSocketTimeout(0);
						}
					} catch (SocketTimeoutException e) {
						e.printStackTrace();
						messageMonitorFlag = false;
						app.sendEmptyMessageToHandler(CommonUtils.LOGIN_TIMEOUT);
					} catch (IOException e) {
						e.printStackTrace();
						messageMonitorFlag = false;
					}
				}
				DLog.i("消息监听已退出");
				DriftService.this.stopSelf();
			}
		};
		monitorThread.start();
	}

	/**
	 * 统一处理收到的消息
	 * 
	 * @param message
	 */
	private void handlingAndDispatchMessage(String message) {
		JSONObject jsonObject = JSON.parseObject(message);
		String type = jsonObject.getString("type");
		jsonObject = jsonObject.getJSONObject("data");
		jsonParser = new JsonParser(app.getMyInfo());
		if (type != null) {
			if (type.equals(JsonFactory.TYPE_PUBLIC_CHAT_CONTENT)) {
				handlingChatEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_ADD_NEARBY_PERSON)) {
				handlingAddNearbyPersonEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_REMOVE_NEARBY_PERSON)) {
				handlingRemoveNearbyPersonEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_INVITE_JOIN_ROOM)) {
				handlingInviteJoinRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_JOIN_ROOM)) {
				handlingJoinRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_QUIT_ROOM)) {
				handlingQuitRoomEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_UPDATE_USER_INFO)) {
				handlingUpdateUserInfoEvent(jsonObject);
			} else if (type.equals(JsonFactory.TYPE_NEARBY_PERSON)) {// 用户做了GoingTo操作
				handlingUpdateLocation(jsonObject);
			}
		}
	}

	private void handlingChatEvent(JSONObject jsonObject) {
		CommonUtils.receiveChatDataFromServer(this, jsonObject.toJSONString());
	}

	private void handlingAddNearbyPersonEvent(JSONObject jsonObject) {
		UserInfo user = jsonParser.parseOneNearbyPersonAndReturn(jsonObject);
		DLog.i(user.getNick() + "上线");
		showToastOnActivity(user.getNick() + "上线，请刷新地图",
				CommonUtils.NOTIFY_ONCE_ACTION);
	}

	private void handlingRemoveNearbyPersonEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		UserInfo user = app.getMyInfo().removeNearbyPerson(id);
		app.getMyInfo().removeRoomPerson(user);
		DLog.i(user.getNick() + "下线");
		showToastOnActivity(user.getNick() + "下线",
				CommonUtils.NOTIFY_ONCE_ACTION);
	}

	private void handlingInviteJoinRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		UserInfo owner = app.getMyInfo().getUserFromNearbyPerson(id);
		owner.setRoomId(id);
		String toast = null;
		toast = (owner.getSex() == 0) ? "邀请你加入她的房间" : "邀请你加入他的房间";
		showToastOnActivity(owner.getNick() + toast,
				CommonUtils.NOTIFY_ONCE_ACTION);
		DLog.i(owner.getNick() + "邀请你加入他的房间");
	}

	private void handlingJoinRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		int roomId = jsonObject.getIntValue("room_id");
		UserInfo user = app.getMyInfo().getUserFromNearbyPerson(id);
		user.setRoomId(roomId);
		if (roomId == app.getMyInfo().getRoomId()) {
			app.getMyInfo().addRoomPerson(user);
			showToastOnActivity(user.getNick() + "加入房间",
					CommonUtils.CHAT_ACTIVITY_JOIN_ROOM, id);
		}
	}

	private void handlingQuitRoomEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		int roomId = jsonObject.getIntValue("room_id");
		UserInfo user = app.getMyInfo().getUserFromNearbyPerson(id);
		user.setRoomId(-1);
		if (roomId == app.getMyInfo().getRoomId()) {
			app.getMyInfo().removeRoomPerson(user);
			showToastOnActivity(user.getNick() + "离开房间",
					CommonUtils.CHAT_ACTIVITY_QUIT_ROOM, id);
		}
	}

	private void handlingUpdateUserInfoEvent(JSONObject jsonObject) {
		int id = jsonObject.getIntValue("id");
		String newNick = jsonObject.getString("nick");
		int newSex = jsonObject.getIntValue("sex");
		UserInfo user = app.getMyInfo().getUserFromNearbyPerson(id);
		user.setNick(newNick);
		user.setSex(newSex);
		user = app.getMyInfo().getUserFromRoomPerson(id);
		if (user != null) {
			user.setNick(newNick);
			user.setSex(newSex);
		}
	}

	private void handlingUpdateLocation(JSONObject jsonObject) {
		jsonParser.parseChangeLocationJson(jsonObject);
		showToastOnActivity("更改成功！", CommonUtils.NOTIFY_ONCE_ACTION);
	}

	/**
	 * 
	 * @param message
	 * @param type
	 * @param args
	 *            额外的参数，id什么的
	 */
	private void showToastOnActivity(String message, int type, int... args) {
		Bundle bundle = new Bundle();
		bundle.putString("data", message);
		Message msg = new Message();
		msg.setData(bundle);
		msg.what = type;
		if (args.length != 0) {
			msg.arg1 = args[0];
		}
		app.sendMessageToHandler(msg);
	}

	private void clearUp() {
		messageMonitorFlag = false;
		if (isRegisterReceiver) {
			unregisterReceiver(sendMessageReceiver);
			isRegisterReceiver = false;
		}
		if (connection != null) {
			connection.closeIOAndSocket();
			connection = null;
		}
		if (heartbeatTask != null) {
			heartbeatTask.cancel();
			heartbeatTask = null;
		}
		app = null;
	}
}
